﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;

using Infrastructure.Core.IOC;
using Infrastructure.Utility;

using SMG.Application.DTO.Migration;
using SMG.ServiceContract.Migration;
using SMG.Monitor.Domain.Models;
using SMG.Application.DTO.Program;
using SMG.ServiceContract.Program;
using Infrastructure.Core.Loging;


namespace SMG.Monitor.Domain.Processor
{
    /// <summary>
    /// 模板处理类
    /// </summary>
    public class TemplateProcessor : IProcessor
    {
        /// <summary>
        /// 节目单迁移服务
        /// </summary>
        IPlayMoveService playMoveService = ServiceLocator.Instance.Resolve<IPlayMoveService>();
        IChannelService channelService = ServiceLocator.Instance.Resolve<IChannelService>();
        //日志服务
        ILogger logServer = LogService.GetInstance(LogType.Text);

        /// <summary>
        /// 频道列表
        /// </summary>
        List<ChannelDto> channels;

        //外网资源服务器地址
        String OutsideStoreServer = ConfigurationManager.AppSettings["OutsideStoreServer"];
        //中间存储服务器地址
        String TranslateStoreServer = ConfigurationManager.AppSettings["TranslateStoreServer"];

        public TemplateProcessor() {
            channels = channelService.QueryChannelAll().ToList();
            if (channels == null) channels = new List<ChannelDto>();
        }

        public void Preprocess(PlayRecordDto playRecord)
        {
            try
            {
                #region Validate

                if (String.IsNullOrEmpty(playRecord.PlayContent))
                    throw new Exception("节目单内容为空");

                var templateModel = SerializeUtility.XmlDeserialize<TemplateModel>(playRecord.PlayContent);
                if (templateModel == null)
                    throw new Exception(String.Format("节目单内容结构异常:{0}", playRecord.PlayContent));

                #endregion

                var result = false;
                if (playRecord.TaskStatus == 0)
                {
                    result = GenFirstMoveTask(templateModel, playRecord);
                    if (result) playRecord.TaskStatus = 1;
                }
                else if (playRecord.TaskStatus == 1 && playRecord.MoveStatus == 1)
                {
                    result = GenSecondMoveTask(playRecord);
                    if (result) playRecord.TaskStatus = 2;
                }
            }
            catch (Exception ex)
            {
                //logServer.Info("FirstTaskDispatcher.Dispatching.ExceptionIn", ex.Message);
                playRecord.TaskStatus = 9;
            }
            finally
            {
                //临时方法，解锁
                playMoveService.UnLockPlayRecord(playRecord);
            }
        }

        #region Private Methods

        List<FirstMoveTaskDetailDto> FirstTaskDetailMapping(Template template)
        {
            if (template == null) return null;

            var taskDetails = new List<FirstMoveTaskDetailDto>();
            var detail = new FirstMoveTaskDetailDto()
            {
                ListId = template.TemplateId,
                FileName = template.TemplateName,
                SourcePath = template.TemplateFolder,
                TargetPath = template.TemplateFolder,
                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now
            };
            taskDetails.Add(detail);
            return taskDetails;
        }

        /// <summary>
        /// 生成一级任务
        /// </summary>
        /// <param name="playRecord"></param>
        /// <returns></returns>
        private Boolean GenFirstMoveTask(TemplateModel templateModel, PlayRecordDto playRecord)
        {
            var taskDict = new Dictionary<FirstMoveTaskDto, IEnumerable<FirstMoveTaskDetailDto>>();

            var channelIds = String.Empty;
            foreach (var template in templateModel.Templates)
            {
                foreach (var channelId in template.Channels)
                {
                    channelIds += channelId + ",";
                    var channel = channels.FirstOrDefault(c => c.ChannelId == channelId);

                    #region 添加一级任务

                    //主任务
                    var taskDto = new FirstMoveTaskDto()
                    {
                        Code = "",
                        PlayID = playRecord.ID,
                        ListId = template.TemplateId,
                        ChannelId = channelId,
                        SourceServer = OutsideStoreServer,
                        TargetServer = TranslateStoreServer,
                        Status = 0,
                        CreateTime = DateTime.Now,
                        UpdateTime = DateTime.Now
                    };

                    //任务详细列表
                    var taskDetails = FirstTaskDetailMapping(template);
                    taskDetails.ForEach(detail =>
                    {
                        detail.PlayID = playRecord.ID;
                        detail.ChannelId = channelId;
                    });

                    taskDict.Add(taskDto, taskDetails);

                    #endregion
                }
            }
            //保存
            var result = playMoveService.AddFirstMoveTask(taskDict);
            playRecord.ChannelId = channelIds;
            playRecord.TaskStatus = 1;

            return true;
        }
        /// <summary>
        /// 生成二级任务
        /// </summary>
        /// <param name="playRecord"></param>
        /// <returns></returns>
        private Boolean GenSecondMoveTask(PlayRecordDto playRecord)
        {
            var taskDict =new Dictionary<SecondMoveTaskDto, IEnumerable<SecondMoveTaskDetailDto>>();

            var firstTaskStateList = playMoveService.QueryFirstTaskState(playRecord.ID);
            var firstTaskDetailStates = playMoveService.QueryFirstTaskDetailState(playRecord.ID);
            if (firstTaskStateList == null || firstTaskDetailStates == null) return false;
            foreach (var firstTask in firstTaskStateList)
            {
                var firstTaskDetails = firstTaskDetailStates.Where(f => f.MainTaskID == firstTask.ID);
                var channel = channels.FirstOrDefault(c => c.ChannelId == firstTask.ChannelId);
                //主任务
                var taskDto = new SecondMoveTaskDto()
                {
                    Code = "",
                    PlayID = playRecord.ID,
                    ChannelId = firstTask.ChannelId,
                    ListId = firstTask.ListId,
                    SourceServer = TranslateStoreServer,
                    TargetServer = channel == null ? "" : channel.FolderMediaMaster,
                    Status = 0,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now
                };
                //任务详细列表
                var taskDetails = new List<SecondMoveTaskDetailDto>();
                foreach (var firstDetail in firstTaskDetails)
                {
                    var detail = new SecondMoveTaskDetailDto()
                    {
                        PlayID = firstDetail.PlayID,
                        ChannelId = firstDetail.ChannelId,
                        ListId = firstDetail.ListId,
                        ItemId = firstDetail.ItemId,
                        FileName = firstDetail.FileName,
                        FileType = firstDetail.FileType,
                        IsHD = firstDetail.IsHD,
                        SourcePath = firstDetail.TargetPath,
                        TargetPath = firstDetail.TargetPath,
                        CreateTime = DateTime.Now,
                        UpdateTime = DateTime.Now
                    };
                    taskDetails.Add(detail);
                }

                taskDict.Add(taskDto, taskDetails);
            }

            var result = playMoveService.AddSecondMoveTask(taskDict);
            playRecord.TaskStatus = 2;
            return result;
        }

        #endregion

    }
}
